The Digital Twin(DT) Execution Report shows the results of a DT execution.
%load_ext autotime
time: 228 µs (started: 2021-11-10 17:48:11 -05:00)
import pandas as pd
import plotly.express as px
import json
import os
import plotly.offline as pyo
pyo.init_notebook_mode()
time: 1.16 s (started: 2021-11-10 17:48:11 -05:00)
base_path = "../../data/runs/2021-06-09 16:49:23.697639-"
time: 273 µs (started: 2021-11-10 17:48:12 -05:00)
# Parameters
base_path = "/Users/santteegt/tokenengineering/RAI/reflexer-digital-twin/data/runs/2021-11-10 22:19:24.921029-"
time: 296 µs (started: 2021-11-10 17:48:13 -05:00)
meta_path = base_path + "meta.json"
historical_path = base_path + "historical.csv.gz"
backtesting_path = base_path + "backtesting.csv.gz"
extrapolation_path = base_path + "extrapolation.csv.gz"
time: 543 µs (started: 2021-11-10 17:48:13 -05:00)
with open(meta_path, 'r') as fid:
metadata = json.load(fid)
for i, row in metadata.items():
print(f"{i}: {row}")
print("---")
createdAt: 2021-11-10 22:19:24.921029 initial_backtesting_timestamp: 2021-10-18 22:37:31 final_backtesting_timestamp: 2021-11-01 19:07:46 --- time: 1.78 ms (started: 2021-11-10 17:48:13 -05:00)
historical_df = pd.read_csv(historical_path).assign(origin='historical').iloc[1:].assign(subset=-1)
backtesting_df = pd.read_csv(backtesting_path).assign(origin='backtesting').iloc[1:]
extrapolation_df = pd.read_csv(extrapolation_path).assign(origin='extrapolation')
historical_df.loc[:, 'seconds_passed'] = backtesting_df.seconds_passed
past_df = (pd.concat([historical_df, backtesting_df])
.reset_index(drop=True)
.assign(seconds_passed=lambda df: df.seconds_passed - df.seconds_passed.min())
)
extrapolation_df.loc[:, 'seconds_passed'] += past_df.seconds_passed.max()
df = pd.concat([past_df, extrapolation_df])
df = (df
.assign(hours_passed=lambda df: df.seconds_passed / (60 * 60))
.assign(days_passed=lambda df: df.seconds_passed / (24 * 60 * 60))
)
initial_time = pd.Timestamp(metadata['initial_backtesting_timestamp'])
deltas = df.hours_passed.map(lambda x: pd.Timedelta(x, unit='h'))
times = initial_time + deltas
df = df.assign(timestamp=times).reset_index()
last_time = df.query('origin == "extrapolation"').timestamp.min()
# Wrangling for extrapolation scenarios
def extrapolation_origin(_df):
df = (_df.query("origin == 'extrapolation'")
.assign(use_ewm_model=lambda df: df.use_ewm_model.fillna(0).astype(int))
.assign(convergence_swap_intensity=lambda df: df.convergence_swap_intensity.fillna(0))
)
s = df.apply(lambda row: f"extrapolation (ewm={row.use_ewm_model}, csi={row.convergence_swap_intensity :.0%})", axis=1)
return s
s = extrapolation_origin(df)
df.loc[s.index, 'origin'] = s
time: 1.99 s (started: 2021-11-10 17:48:13 -05:00)
value_cols = ('eth_price', 'market_price')
id_cols = {'timestamp', 'origin', 'subset'}
fig_df = (df.melt(id_vars=id_cols, value_vars=value_cols)
.replace({'market_price': 'RAI Market Price (USD/RAI)'})
.replace({'eth_price': 'ETH Price (USD/RAI)'})
)
fig = px.line(fig_df,
x='timestamp',
y='value',
color='origin',
facet_row='variable',
line_group='subset',
labels={'market_price': 'RAI Market Price in USD'},
title='Prices over time')
fig.update_traces(line=dict(width=0.5),
marker=dict(opacity=0.05, size=5),
mode='lines+markers')
fig.add_vline(initial_time.timestamp() * 1000,
annotation_text=initial_time.strftime('%Y-%m-%d %Hh'))
fig.add_vline(last_time.timestamp() * 1000,
annotation_text=last_time.strftime('%Y-%m-%d %Hh'))
fig.add_vrect(x0=last_time,
x1=fig_df.timestamp.max(),
annotation_text="Extrapolation",
annotation_position="top right",
fillcolor="cyan",
opacity=0.05)
fig.update_yaxes(matches=None)
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.show()
time: 4.36 s (started: 2021-11-10 17:48:16 -05:00)
In the plots above we evaluate the Eth price data (upper) and the Rai market price data (lower) showing the historical data and the forward extrapolation under various assumptions Exponential Moving Average (EWM) and optimal swap assumptions. The CSI number indicating the maximum intensity of the 'optimal swap'.
value_cols = ('redemption_price',
'redemption_rate',
'redemption_rate_annual',
'proportional_error',
'integral_error')
id_cols = {'timestamp', 'origin', 'subset'}
fig_df = (df.assign(redemption_rate_annual=lambda df: df.redemption_rate ** (24 * 365))
.melt(id_vars=id_cols, value_vars=value_cols)
.replace({'redemption_price': 'Redemption Price (USD/RAI)'})
.replace({'redemption_rate': 'Redemption Rate (%/hours)'})
.replace({'redemption_rate_annual': 'Redemption Rate (%/year)'})
.replace({'proportional_error': 'Proportional Error (USD/RAI)'})
.replace({'integral_error': 'Integral Error (USD * s / RAI)'})
)
fig = px.line(fig_df,
x='timestamp',
y='value',
color='origin',
facet_row='variable',
line_group='subset',
height=1200,
title='Controller State over time')
fig.update_traces(line=dict(width=0.5),
marker=dict(opacity=0.05, size=5),
mode='lines+markers')
fig.add_vline(initial_time.timestamp() * 1000,
annotation_text=initial_time.strftime('%Y-%m-%d %Hh'))
fig.add_vline(last_time.timestamp() * 1000,
annotation_text=last_time.strftime('%Y-%m-%d %Hh'))
fig.add_vrect(x0=last_time,
x1=fig_df.timestamp.max(),
annotation_text="Extrapolation",
annotation_position="top right",
fillcolor="cyan",
opacity=0.05)
fig.update_yaxes(matches=None)
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.show()